package com.recharge.service.httpInterFace;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.common.util.Constant;
import com.recharge.common.util.Des3Encryption;
import com.recharge.common.util.MD5Util;
import com.recharge.common.util.TemplateUtils;
import com.recharge.common.util.http.HttpClientUtil;
import com.recharge.domain.query.OrderStatusQueryDO;
import com.recharge.domain.vo.GoodsChannelDO;
import com.recharge.domain.vo.ProviderApiDO;
import com.recharge.domain.vo.ProviderCallbackDO;
import com.recharge.service.OrderService;
import com.recharge.service.ProviderApiService;
import com.recharge.service.httpInterFace.statusEnum.DaoChunStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 道春接口
 */
@Service
public class DaoChunHTTPImpl implements ProviderHTTPService {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    ProviderApiService providerApiService;

    @Autowired
    OrderService orderService;

    @Override
    public ResultDO commitOrder(GoodsChannelDO domain) {
        if (!verifyCommitParam(domain)) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("订单提交 >> 参数缺失 %s", domain.toString())
                    , "请求参数缺失"
                    , null);
        }
        // 添加存根
        ProviderCallbackDO callbackDO = new ProviderCallbackDO();
        callbackDO.setSerialNumber(domain.getProviderSerialNumber());
        callbackDO.setProviderId(domain.getProviderId());
        callbackDO.setOrderNo(domain.getOrderNo());
        callbackDO.setStatus(Constant.CALL_BACK_PROCESS);
        ResultDO result = providerApiService.addCallback(callbackDO);
        if (!result.isSuccess()) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("订单提交 >> 订单%s添加凭证数据失败", domain.getProviderSerialNumber())
                    , "添加回调存根信息失败"
                    , null);
        }

        Map<String, String> signInfo = new HashMap<>();

        /**
         * customerNo	商户编号	N	代充平台商户编号，道春提供
         * requestId	订单号	N	商户订单号必须保证唯一性，长度5-32个字符
         * proType	产品类型	N	详见【附录1】
         * mobileNo	代充号码	N	需要代充值的号码
         * province	省份	Y	代充号码所在的省份, 详见【附录2】
         * cardNo	卡号	N	充值卡卡号（3DES加密后的密文）
         * cardPwd	卡密	N	充值卡卡密（3DES加密后的密文）
         * money	卡面额	N	充值卡面额
         * callbackUrl	回调地址	Y	为空时将使用我方平台绑定的地址
         * 为空时不参与签名 (V2.1新增)
         * sign	签名	N	使用MD5算法生成的加密验证字符串
         */
        //商户编号
        signInfo.put("customerNo", String.valueOf(domain.getUserId()));
        //商户订单号
        signInfo.put("requestId", domain.getProviderSerialNumber());
        //产品类型
        switch (domain.getServiceProvider()) {
            case 1: //移动
                signInfo.put("proType", "MOBILE");
                break;
            case 2:  //电信
                signInfo.put("proType", "TELECOM");
                break;
            case 3:  //联通
                signInfo.put("proType", "UNICOM");
                break;
            default:
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                        , String.format("订单提交 >> 订单%s未查询到运营商", domain.getProviderSerialNumber())
                        , "未查询到运营商"
                        , null);
        }
        //代充号码
        signInfo.put("mobileNo", domain.getRechargeNumber());
        //充值卡序号(密文)
        signInfo.put("cardNo", Des3Encryption.encryptToHex(domain.getPrivateKey(), domain.getCardNo()));
        //充值卡密码(密文)
        signInfo.put("cardPwd", Des3Encryption.encryptToHex(domain.getPrivateKey(), domain.getCardPassword()));
        //充值卡面值(元)
        signInfo.put("money", String.valueOf(domain.getAmount() / 1000));
        //回调地址
        signInfo.put("notifyUrl", domain.getCallback());

        String afterSign;
        try {
            // customerNo|requestId|proType||mobileNo|cardNo|cardPwd|money|callbackUrl#key
            String beforeSign = String.format("%s|%s|%s||%s|%s|%s|%s|%s#%s"
                    , domain.getUserId(), domain.getProviderSerialNumber(), signInfo.get("proType"), domain.getRechargeNumber()
                    , signInfo.get("cardNo"), signInfo.get("cardPwd"), domain.getAmount() / 1000, domain.getCallback(), domain.getPrivateKey());

            logger.debug("before_sign: " + beforeSign);
            afterSign = MD5Util.md5(beforeSign).toUpperCase();
        } catch (Exception e) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("渠道商ID: %s HTTP请求参数构建失败", domain.getProviderId())
                    , "HTTP请求参数构建失败"
                    , null);
        }

        //签名
        signInfo.put("sign", afterSign);

        // 发送请求
        logger.warn(String.format("订单提交 >> 发送GET请求(订单号%s): %s?%s", domain.getProviderSerialNumber(), domain.getRequestUrl(), signInfo.toString()));
        String sendResult = HttpClientUtil.doGet(domain.getRequestUrl(), signInfo);
        switch (sendResult) {
            case "500":
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                        , String.format("订单提交 >> 订单号 %s -> 订单提交供货商HTTP请求失败", domain.getProviderSerialNumber())
                        , "HTTP请求失败"
                        , sendResult);
            case "504":
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                        , String.format("订单提交 >> 订单号 %s -> 订单提交供货商HTTP请求超时", domain.getProviderSerialNumber())
                        , "HTTP请求超时"
                        , sendResult);
            case "":
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                        , String.format("订单提交 >> 订单号 %s -> 订单提交供货商HTTP请求没有返回信息", domain.getProviderSerialNumber())
                        , "订单提交没有返回信息"
                        , sendResult);
        }
        logger.warn(String.format("订单提交 >> 请求返回信息: 订单号%s -> %s", domain.getProviderSerialNumber(), sendResult));

        //获取状态码消息
        String desc = DaoChunStatus.getMessage(sendResult, 1);

        // 状态码: 提交失败
        String[] array = {"4001", "4002", "4004", "4005", "4006", "4007", "4008", "4011", "4012", "4013", "4014", "4015", "4016", "4017"};

        if ("0000".equals(sendResult)) { //成功
            logger.debug(String.format("订单提交 >> 订单 %s -> 订单提交成功|%s", domain.getProviderSerialNumber(), sendResult));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.BUSINESS_RECHARGE_RETURN_STATUS_SUCCESS);
            result.setModel(ResultDO.SECOND_MODEL_KEY, "");
            result.setModel(ResultDO.THIRD_MODEL_KEY, desc);
            return result;
        } else if ("4003".equals(sendResult)) { //卡密无效
            return returnFail(true
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_CARD_INVALID
                    , String.format("订单提交 >> 订单 %s -> 订单卡密无效|%s", domain.getProviderSerialNumber(), sendResult)
                    , String.format("%s %s", desc, sendResult)
                    , sendResult);
        } else if (Arrays.asList(array).contains(sendResult)) {//失败
            return returnFail(true
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("订单提交 >> 订单 %s -> 订单提交失败|%s", domain.getProviderSerialNumber(), sendResult)
                    , String.format("%s %s", desc, sendResult)
                    , sendResult);
        } else if ("5000".equals(sendResult)) {//未确认
            return returnFail(true
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                    , String.format("订单提交 >> 订单 %s -> 订单未确认|%s", domain.getProviderSerialNumber(), sendResult)
                    , String.format("%s %s", desc, sendResult)
                    , sendResult);
        } else {//未知
            return returnFail(true
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                    , String.format("订单提交 >> 订单 %s -> 订单未知|%s", domain.getProviderSerialNumber(), sendResult)
                    , String.format("%s %s", desc, sendResult)
                    , sendResult);
        }

    }

    @Override
    public ResultDO backOrder(ProviderApiDO domain, String paramStr, String bodyStr) {
        ResultDO result = new ResultSupport();
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(paramStr);
            logger.debug("订单异步回调 >> " + domain.getProviderNo() + "解析后数据: " + jsonObject.toJSONString());
        } catch (Exception e) {
            logger.debug("订单异步回调 >> " + domain.getProviderNo() + "解析失败:" + paramStr);
        }
        if (jsonObject == null) {
            logger.debug("订单异步回调 >> 收到异步回调,但是没有回调信息");
            result.setModel(ResultDO.FIRST_MODEL_KEY, "fail");
            return result;
        }
        /*
        requestId	订单号	N	同请求接口的订单号
        customerNo	商户编号	N	商户编号，道春提供
        orderId	道春平台订单号	N	道春平台订单号
        successAmount	代充值成功金额	N	单位为元
        finishDate	代充完成时间	N	格式：yyyyMMddHHmmss
        deductAmount	扣款手续费	N	单位为元（扣除商户账户的金额）
        actualAmount	卡实际面值	N	充值卡实际对应的面值，单位为元
        status	状态	N	见附录3
        sign	数据签名	N	使用MD5算法生成的加密验证字符串
         */

        //平台流水号
        String outTradeNo = jsonObject.getString("requestId");
        //商户编号
        String customerNo = jsonObject.getString("customerNo");
        //上游流水号
        String orderNo = jsonObject.getString("orderId");
        //充值金额(元)
        String successAmount = jsonObject.getString("successAmount");
        //完成时间
        String finishTime = jsonObject.getString("finishDate");
        //代充手续费
        String feeAmount = jsonObject.getString("deductAmount");
        //充值卡面值
        String actualAmount = jsonObject.getString("actualAmount");
        //充值状态
        String status = jsonObject.getString("status");
        //校验签名
        String returnSign = jsonObject.getString("sign");


        //加密前签名 requestId|customerNo|orderId|successAmount|finishDate|deductAmount|actualAmount|status#key
        String beforeVerifySign = String.format("%s|%s|%s|%s|%s|%s|%s|%s#%s"
                , outTradeNo, customerNo, orderNo, successAmount, finishTime, feeAmount, actualAmount, status, domain.getPrivateKey());

        String afterVerifySign = "";
        try {
            afterVerifySign = MD5Util.md5(beforeVerifySign, 32).toUpperCase();
        } catch (Exception e) {
            logger.debug("订单异步回调 >> 订单(" + outTradeNo + ")验签加密失败" + e.getMessage());
        }
//        logger.debug("签名验证: after >>"+afterVerifySign);
        if (!afterVerifySign.equals(returnSign)) {
            logger.debug("订单异步回调 >> 签名校验: 加密前 >>" + beforeVerifySign);
            logger.debug(String.format("订单异步回调 >> 订单:%s 签名校验不一致 {本地签名:%s 返回签名:%s }", outTradeNo, afterVerifySign, returnSign));
            result.setModel(ResultDO.FIRST_MODEL_KEY, "fail");
            return result;
        }

        //状态码,卡密失败
        String[] array = {"101", "102", "103", "104"};
        //状态码,订单失败
        String[] array2 = {"105", "201", "400", "500", "600", "602"};

        //判断订单状态
        if (status.equals("SUCCESS")) { // 成功
            logger.debug(String.format("订单异步回调 >> %s 成功 status: %s", outTradeNo, status));
            result = providerApiService.updateCallback(outTradeNo, "", orderNo, Constant.CALL_BACK_SUCCESS);
        } else if (status.equals("DEALING")) { // 充值中
            logger.debug(String.format("订单异步回调 >> %s 充值中 status: %s (未做处理)", outTradeNo, status));
//            result = providerApiService.updateCallback(outTradeNo, "", orderNo, Constant.CALL_BACK_PROCESS);
        } else if (status.equals("601")) { // 人工确认
            logger.debug(String.format("订单异步回调 >> %s 未确认 status: %s", outTradeNo, status));
            result = providerApiService.updateCallback(outTradeNo, "", orderNo, Constant.CALL_BACK_NUKNOW);
        } else if (Arrays.asList(array).contains(status)) { //卡密失败
            logger.debug(String.format("订单异步回调 >> %s 卡密失败 status: %s", outTradeNo, status));
            result = providerApiService.updateCallback(outTradeNo, "", orderNo, Constant.CALL_BACK_CARD_INVALID);
        } else if (Arrays.asList(array2).contains(status)) { //订单失败
            logger.debug(String.format("订单异步回调 >> %s 充值失败 status: %s", outTradeNo, status));
            result = providerApiService.updateCallback(outTradeNo, "", orderNo, Constant.CALL_BACK_FAIL);
        } else { //未知
            logger.debug(String.format("订单异步回调 >> %s 未确认 status: %s", outTradeNo, status));
            result = providerApiService.updateCallback(outTradeNo, "", orderNo, Constant.CALL_BACK_NUKNOW);
        }
        if (!result.isSuccess()) {
            logger.debug(String.format("订单异步回调 >> %s 修改订单状态失败", outTradeNo));
            result.setModel(ResultDO.FIRST_MODEL_KEY, "FAIL");
            return result;
        }
        result.setModel(ResultDO.FIRST_MODEL_KEY, "success");
        return result;

    }

    /**
     * 订单查询
     * <p>
     * 只能查询30天内的订单
     * </p>
     * <p>
     * success标志: 成功发送http请求并解析成功返回true, 否则为false;
     * </p>
     *
     * @param domain 订单查询参数
     * @return FIRST_MODEL_KEY: 订单状态
     * SECOND_MODEL_KEY: 充值凭证号
     * THIRD_MODEL_KEY: 订单查询返回信息
     * FOURTH_MODEL_KEY: 如果订单有延迟可失败的则返回延迟时间(单位:分)
     */
    @Override
    public ResultDO queryOrder(OrderStatusQueryDO domain) {
        ResultDO result = new ResultSupport();

        Map<String, String> requestParamMap = new HashMap<>();
        requestParamMap.put("requestId", domain.getSerialNo());
        requestParamMap.put("customerNo", domain.getUserId());
        String sign = "";
        try {
            sign = MD5Util.md5(domain.getSerialNo() + "|" + domain.getUserId() + "#" + domain.getPrivateKey()).toUpperCase();
        } catch (Exception e) {
            logger.debug("查询订单 >> 订单" + domain.getSerialNo() + " 签名加密失败" + e.getMessage());
            result.setSuccess(false);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "签名加密失败");
            return result;
        }
        requestParamMap.put("sign", sign);

        // 发送请求
        logger.debug(String.format("查询订单 >> 发送GET请求(订单号%s): url %s , param %s", domain.getSerialNo(), domain.getOrderFindUrl(), requestParamMap));
        String sendResult = HttpClientUtil.doGet(domain.getOrderFindUrl(), requestParamMap);
        switch (sendResult) {
            case "500":
                logger.debug(String.format("查询订单 >> 订单 %s -> HTTP请求失败|500", domain.getSerialNo()));
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "HTTP请求失败");
                return result;
            case "504":
                logger.debug(String.format("查询订单 >> 订单 %s -> HTTP请求超时|504", domain.getSerialNo()));
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "HTTP请求超时");
                return result;
            case "":
                logger.debug(String.format("查询订单 >> 订单 %s -> 请求没有返回信息", domain.getSerialNo()));
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "请求没有返回信息");
                return result;
        }
        logger.debug(String.format("查询订单 >> 请求返回信息: 订单 %s -> %s", domain.getSerialNo(), sendResult));

        // 解析请求返回结果转换为json对象
        JSONObject resultJson = new JSONObject();
        try {
            resultJson = JSON.parseObject(sendResult);
        } catch (Exception e) {
            logger.debug(String.format("查询订单 >> 订单" + domain.getSerialNo() + " 请求返回结果解析JSON失败: %s", sendResult));
        }
        if (resultJson.size() == 0) {
            logger.debug("查询订单 >> 订单" + domain.getSerialNo() + " 未找到请求返回结果");
            result.setSuccess(false);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "未找到请求返回结果");
            return result;
        }
        String code = null;

        try {
            code = resultJson.getString("resultCode");
        } catch (Exception e) {
            logger.debug(String.format("查询订单 >> 获取返回信息失败: 订单 %s -> %s", domain.getSerialNo(), sendResult));
        }
        if (code == null) {
            logger.debug("查询订单 >> 订单" + domain.getSerialNo() + " 未获取到请求返回状态码");
            result.setSuccess(false);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "未获取到请求返回状态码");
            return result;
        }
        //返回信息字符串
        String desc = DaoChunStatus.getMessage(code, 1);

        // 查询状态码: 查询失败
        String[] array = {"4002", "4007", "4008", "4012", "4013", "4016", "500"};

        if ("200".equals(code)) { //请求成功
            String status = null;
            try {
                status = resultJson.getString("status");
                String beforeSign = String.format("%s|%s|%s|%s|%s|%s|%s|%s|%s#%s", code, resultJson.get("customerNo")
                        , resultJson.get("requestId"), status, resultJson.get("successAmount"), resultJson.get("finishDate")
                        , resultJson.get("orderId"), resultJson.get("deductAmount"), resultJson.get("actualAmount"), domain.getPrivateKey());
                if (!resultJson.getString("sign").equals(MD5Util.md5(beforeSign).toUpperCase())) {
                    logger.debug("查询订单 >>订单" + domain.getSerialNo() + " 请求结果返回验签失败");
                    result.setSuccess(false);
                    result.setModel(ResultDO.THIRD_MODEL_KEY, "请求结果返回验签失败");
                    return result;
                }
            } catch (Exception e) {
                logger.debug(String.format("查询订单 >> 获取订单返回信息失败: 订单 %s -> %s", domain.getSerialNo(), sendResult));
            }
            if (status == null) {
                logger.debug("查询订单 >> 订单" + domain.getSerialNo() + " 未获取到订单返回状态码");
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "未获取到订单返回状态码");
                return result;
            }
            //返回信息字符串
            desc = DaoChunStatus.getMessage(status, 2);
            //订单状态码: 失败
            String[] array2 = {"101", "102", "103", "104", "105", "201", "400", "500", "600", "602"};
            if (status.equals("SUCCESS")) { //成功
                logger.debug(String.format("查询订单 >> 订单 %s -> 订单成功|%s", domain.getSerialNo(), desc));
                result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_SUCCESS);
                result.setModel(ResultDO.SECOND_MODEL_KEY, "");
            } else if (Arrays.asList(array2).contains(status)) {//失败
                logger.debug(String.format("查询订单 >> 订单 %s -> 订单失败|%s", domain.getSerialNo(), desc));
                result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_FAIL);
            } else if (status.equals("DEALING")) {//充值中
                logger.debug(String.format("查询订单 >> 订单 %s -> 订单充值中|%s", domain.getSerialNo(), desc));
                result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_PROCESS);
            } else if (status.equals("601")) { //待确认
                logger.debug(String.format("查询订单 >> 订单 %s -> 订单未确认|%s", domain.getSerialNo(), desc));
                result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NUKNOW);
            } else {//未知
                logger.debug(String.format("查询订单 >> 订单 %s -> 订单未知|%s %s", domain.getSerialNo(), desc, status));
                result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NUKNOW);
            }
        } else if (code.equals("400")) {//订单不存在
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单查询订单不存在|%s", domain.getSerialNo(), desc));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NOT_EXIST);
            result.setModel(ResultDO.FOURTH_MODEL_KEY, 1);
        } else if (Arrays.asList(array).contains(code)) {//请求失败
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单查询请求失败|%s", domain.getSerialNo(), desc));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NUKNOW);
        } else {//未知
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单查询请求失败|%s", domain.getSerialNo(), desc));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NUKNOW);
        }
        result.setModel(ResultDO.THIRD_MODEL_KEY, desc);
        return result;
    }

    @Override
    public ResultDO queryBalance(ProviderApiDO domain) {
        ResultDO result = new ResultSupport();
        if (domain.getPrivateKey() == null || domain.getUserId() == null) {
            result.setSuccess(false);
            result.setModel(ResultDO.FIRST_MODEL_KEY, "查询失败");
            return result;
        }
        Map<String, String> requestParamMap = new HashMap<>();
        requestParamMap.put("customerNo", domain.getUserId());
        String sign = "";
        try {
            sign = MD5Util.md5(domain.getUserId() + "#" + domain.getPrivateKey()).toUpperCase();
        } catch (Exception e) {
            logger.debug("余额查询 >> 签名加密失败" + e.getMessage());
            result.setSuccess(false);
            result.setModel(ResultDO.FIRST_MODEL_KEY, "签名加密失败");
            return result;
        }
        requestParamMap.put("sign", sign);

        // 发送请求
        String sendResult = HttpClientUtil.doGet(domain.getBalanceFindUrl(), requestParamMap);
        logger.debug(String.format("余额查询 >> 余额查询返回信息: 供应商账号 %s -> %s", domain.getUserId(), sendResult));

        // 解析请求返回结果转换为json对象
        JSONObject resultJson = new JSONObject();
        try {
            resultJson = JSON.parseObject(sendResult);
        } catch (Exception e) {
            logger.debug(String.format("余额查询 >> 请求返回结果解析JSON失败: %s", sendResult));
        }
        if (resultJson.size() == 0) {
            result.setSuccess(false);
            logger.debug(String.format("余额查询 >> 供应商账号: %s -> 余额查询没有返回信息", domain.getUserId()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, "查询失败");
            return result;
        }
        String code = null;
        String balance = null;
        String desc = "";
        try {
            code = resultJson.getString("resultCode");
            if (code.equals("200")) {
                balance = resultJson.getString("balance");
            }
        } catch (Exception e) {
            logger.debug(String.format("余额查询 >> 获取返回信息失败: 供应商账号%s -> %s", domain.getUserId(), sendResult));
        }
        if (balance == null) {
            logger.debug(String.format("余额查询 >> 供应商账号 %s -> 余额查询失败 | %s", domain.getUserId(), desc));
            balance = DaoChunStatus.getMessage(code, 1);
        }
        result.setModel(ResultDO.FIRST_MODEL_KEY, balance);
        return result;
    }

    /**
     * 验证提交参数
     *
     * @param domain
     * @return boolean
     */
    private boolean verifyCommitParam(GoodsChannelDO domain) {
        // 商户ID
        if (TemplateUtils.isEmpty(domain.getProviderId())) {
            return false;
        }
        // 上游账号
        if (TemplateUtils.isEmpty(domain.getUserId())) {
            return false;
        }
        // 流水号
        if (TemplateUtils.isEmpty(domain.getProviderSerialNumber())) {
            return false;
        }
        // 充值号码
        if (TemplateUtils.isEmpty(domain.getRechargeNumber())) {
            return false;
        }
        // 卡密账号
        if (TemplateUtils.isEmpty(domain.getCardNo())) {
            return false;
        }
        // 卡密密码
        if (TemplateUtils.isEmpty(domain.getCardPassword())) {
            return false;
        }
        // 面值
        if (TemplateUtils.isEmpty(domain.getAmount())) {
            return false;
        }
        // 运营商
        if (TemplateUtils.isEmpty(domain.getServiceProvider())) {
            return false;
        }
        // 密钥
        if (TemplateUtils.isEmpty(domain.getPrivateKey())) {
            return false;
        }
        // 回调地址
        if (TemplateUtils.isEmpty(domain.getCallback())) {
            return false;
        }
        return true;
    }

    /**
     * <h2>提交订单返回失败</h2>
     *
     * @param success    是否处理成功
     * @param code       订单状态
     * @param logMessage 失败信息
     * @param message    供货摘要
     * @param entity     返回信息字符串
     * @return FIRST_MODEL_KEY: 订单状态
     * SECOND_MODEL_KEY: 供货摘要
     * THIRD_MODEL_KEY: 上游返回信息字符串
     */
    private ResultDO returnFail(boolean success, int code, String logMessage, String message, String entity) {
        ResultDO result = new ResultSupport();
        result.setSuccess(success);
        result.setModel(ResultDO.FIRST_MODEL_KEY, code);
        result.setModel(ResultDO.SECOND_MODEL_KEY, message);
        result.setModel(ResultDO.THIRD_MODEL_KEY, entity);
        logger.debug(logMessage);
        return result;
    }

    public static void main(String[] args) {
        String a = Des3Encryption.encryptToHex("test12345678901234", "1234567890123456789");
        System.out.println(a);
        System.out.println(a.equals("3c45aac44b04660fe688ead959d6ed48232fa26d4f836f40"));
    }
}
